home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 May: Tool Chest / Developer CD Series May 1996 (Tool Chest) (Apple Computer) (1996).iso / Tool Chest / Development Tools & Languages / Dylan Related / Mindy / Mindy 1.2 - portable sources / libraries / dylan / num.dylan < prev    next >
Encoding:
Text File  |  1995-03-15  |  9.5 KB  |  392 lines  |  [TEXT/ttxt]

  1. module: Dylan
  2. rcs-header: $Header: num.dylan,v 1.9 94/11/28 15:38:51 wlott Exp $
  3.  
  4. //======================================================================
  5. //
  6. // Copyright (c) 1994  Carnegie Mellon University
  7. // All rights reserved.
  8. // 
  9. // Use and copying of this software and preparation of derivative
  10. // works based on this software are permitted, including commercial
  11. // use, provided that the following conditions are observed:
  12. // 
  13. // 1. This copyright notice must be retained in full on any copies
  14. //    and on appropriate parts of any derivative works.
  15. // 2. Documentation (paper or online) accompanying any system that
  16. //    incorporates this software, or any part of it, must acknowledge
  17. //    the contribution of the Gwydion Project at Carnegie Mellon
  18. //    University.
  19. // 
  20. // This software is made available "as is".  Neither the authors nor
  21. // Carnegie Mellon University make any warranty about the software,
  22. // its performance, or its conformity to any specification.
  23. // 
  24. // Bug reports, questions, comments, and suggestions should be sent by
  25. // E-mail to the Internet address "gwydion-bugs@cs.cmu.edu".
  26. //
  27. //======================================================================
  28. //
  29. //  This file contains the support for numbers that isn't built in.
  30. //
  31.  
  32.  
  33. // Predicates.
  34.  
  35. define method odd? (x :: <integer>)
  36.   logbit?(0, x);
  37. end;
  38.  
  39. define method even? (x :: <integer>)
  40.   ~logbit?(0, x);
  41. end;
  42.  
  43. define method zero? (x :: <number>)
  44.   x = 0;
  45. end;
  46.  
  47. define method positive? (x :: <real>)
  48.   x > 0;
  49. end;
  50.  
  51. define method negative? (x :: <real>)
  52.   x < 0;
  53. end;
  54.  
  55. define method integral? (x :: <integer>)
  56.   #t
  57. end;
  58.  
  59. define method integral? (x :: <number>)
  60.   #f
  61. end;
  62.  
  63.  
  64. // Contagion.
  65.  
  66. define method combine-contagion (x :: <fixed-integer>, y :: <extended-integer>)
  67.   values (as (<extended-integer>, x), y);
  68. end method;
  69.  
  70. define method combine-contagion (x :: <extended-integer>, y :: <fixed-integer>)
  71.   values (x, as (<extended-integer>, y));
  72. end method;
  73.  
  74. define method combine-contagion (x :: <rational>, y :: <single-float>)
  75.   values (as (<single-float>, x), y);
  76. end;
  77.  
  78. define method combine-contagion (x :: <single-float>, y :: <rational>)
  79.   values (x, as (<single-float>, y));
  80. end;
  81.  
  82. define method combine-contagion (x :: <rational>, y :: <double-float>)
  83.   values (as (<double-float>, x), y);
  84. end;
  85.  
  86. define method combine-contagion (x :: <double-float>, y :: <rational>)
  87.   values (x, as (<double-float>, y));
  88. end;
  89.  
  90. define method combine-contagion (x :: <rational>, y :: <extended-float>)
  91.   values (as (<extended-float>, x), y);
  92. end;
  93.  
  94. define method combine-contagion (x :: <extended-float>, y :: <rational>)
  95.   values (x, as (<extended-float>, y));
  96. end;
  97.  
  98. define method combine-contagion (x :: <single-float>, y :: <double-float>)
  99.   values (as (<double-float>, x), y);
  100. end;
  101.  
  102. define method combine-contagion (x :: <double-float>, y :: <single-float>)
  103.   values (x, as (<double-float>, y));
  104. end;
  105.  
  106. define method combine-contagion (x :: <single-float>, y :: <extended-float>)
  107.   values (as (<extended-float>, x), y);
  108. end;
  109.  
  110. define method combine-contagion (x :: <extended-float>, y :: <single-float>)
  111.   values (x, as (<extended-float>, y));
  112. end;
  113.  
  114. define method combine-contagion (x :: <double-float>, y :: <extended-float>)
  115.   values (as (<extended-float>, x), y);
  116. end;
  117.  
  118. define method combine-contagion (x :: <extended-float>, y :: <double-float>)
  119.   values (x, as (<extended-float>, y));
  120. end;
  121.  
  122. define method compare-contagion (x :: <real>, y :: <real>)
  123.    combine-contagion (x, y);
  124. end method;
  125.  
  126.  
  127.  
  128. // Additional methods for +, etc.
  129.  
  130. define method \+ (x :: <number>, y :: <number>)
  131.   let (x, y) = combine-contagion(x, y);
  132.   x + y;
  133. end;
  134.  
  135. define method \- (x :: <number>, y :: <number>)
  136.   let (x, y) = combine-contagion(x, y);
  137.   x - y;
  138. end;
  139.  
  140. define method \* (x :: <number>, y :: <number>)
  141.   let (x, y) = combine-contagion(x, y);
  142.   x * y;
  143. end;
  144.  
  145. define method \/ (x :: <real>, y :: <float>)
  146.   let (x, y) = combine-contagion(x, y);
  147.   x / y;
  148. end;
  149.  
  150. define method \/ (x :: <float>, y :: <rational>)
  151.   let (x, y) = combine-contagion(x, y);
  152.   x / y;
  153. end;
  154.  
  155. define method truncate (x :: <integer>)
  156.       => (q :: <integer>, r :: <fixed-integer>);
  157.   truncate/ (x, 1);
  158. end;
  159.  
  160. define method floor (x :: <integer>)
  161.       => (q :: <integer>, r :: <fixed-integer>);
  162.   floor/ (x, 1);
  163. end;
  164.  
  165. define method ceiling (x :: <integer>)
  166.       => (q :: <integer>, r :: <fixed-integer>);
  167.   ceiling/ (x, 1);
  168. end;
  169.  
  170. define method round (x :: <integer>)
  171.       => (q :: <integer>, r :: <fixed-integer>);
  172.   round/ (x, 1);
  173. end;
  174.  
  175. define method floor/ (x :: <extended-integer>, y :: <fixed-integer>)
  176.     => (q :: <extended-integer>, r :: <fixed-integer>);
  177.   let (q, r) = floor/ (x, as(<extended-integer>, y));
  178.   values(q, as(<fixed-integer>, r));
  179. end;
  180.  
  181. define method floor/ (x :: <fixed-integer>, y :: <extended-integer>)
  182.     => (q :: <extended-integer>, r :: <extended-integer>);
  183.   floor/ (as(<extended-integer>, x), y);
  184. end;
  185.  
  186. define method floor/ (x :: <real>, y :: <real>)
  187.     => (q :: <integer>, r :: <real>);
  188.   let res = floor (x / y);
  189.   values (res, x - res * y);
  190. end;
  191.  
  192. define method ceiling/ (x :: <extended-integer>, y :: <fixed-integer>)
  193.     => (q :: <extended-integer>, r :: <fixed-integer>);
  194.   let (q, r) = ceiling/ (x, as(<extended-integer>, y));
  195.   values(q, as(<fixed-integer>, r));
  196. end;
  197.  
  198. define method ceiling/ (x :: <fixed-integer>, y :: <extended-integer>)
  199.     => (q :: <extended-integer>, r :: <extended-integer>);
  200.   ceiling/ (as(<extended-integer>, x), y);
  201. end;
  202.  
  203. define method ceiling/ (x :: <real>, y :: <real>)
  204.     => (q :: <integer>, r :: <real>);
  205.   let res = ceiling (x / y);
  206.   values (res, x - res * y);
  207. end;
  208.  
  209. define method round/ (x :: <extended-integer>, y :: <fixed-integer>)
  210.     => (q :: <extended-integer>, r :: <fixed-integer>);
  211.   let (q, r) = round/ (x, as(<extended-integer>, y));
  212.   values(q, as(<fixed-integer>, r));
  213. end;
  214.  
  215. define method round/ (x :: <fixed-integer>, y :: <extended-integer>)
  216.     => (q :: <extended-integer>, r :: <extended-integer>);
  217.   round/ (as(<extended-integer>, x), y);
  218. end;
  219.  
  220. define method round/ (x :: <real>, y :: <real>)
  221.     => (q :: <integer>, r :: <real>);
  222.   let res = round (x / y);
  223.   values (res, x - res * y);
  224. end;
  225.  
  226. define method truncate/ (x :: <extended-integer>, y :: <fixed-integer>)
  227.     => (q :: <extended-integer>, r :: <fixed-integer>);
  228.   let (q, r) = truncate/ (x, as(<extended-integer>, y));
  229.   values(q, as(<fixed-integer>, r));
  230. end;
  231.  
  232. define method truncate/ (x :: <fixed-integer>, y :: <extended-integer>)
  233.     => (q :: <extended-integer>, r :: <extended-integer>);
  234.   truncate/ (as(<extended-integer>, x), y);
  235. end;
  236.  
  237. define method truncate/ (x :: <real>, y :: <real>)
  238.     => (q :: <integer>, r :: <real>);
  239.   let res = truncate (x / y);
  240.   values(res, x - res * y);
  241. end;
  242.  
  243. define method modulo (x :: <real>, y :: <real>)
  244.   let (quo, rem) = floor/(x, y);
  245.   rem;
  246. end;
  247.  
  248. define method remainder (x :: <real>, y :: <real>)
  249.   let (quo, rem) = truncate/(x, y);
  250.   rem;
  251. end;
  252.  
  253. define method binary-logand (x :: <integer>, y :: <integer>)
  254.   let (x, y) = combine-contagion(x, y);
  255.   binary-logand(x, y);
  256. end;
  257.  
  258. define method binary-logior (x :: <integer>, y :: <integer>)
  259.   let (x, y) = combine-contagion(x, y);
  260.   binary-logior(x, y);
  261. end;
  262.  
  263. define method binary-logxor (x :: <integer>, y :: <integer>)
  264.   let (x, y) = combine-contagion(x, y);
  265.   binary-logxor(x, y);
  266. end;
  267.  
  268. define method \= (x :: <real>, y :: <real>)
  269.   let (x, y) = compare-contagion(x, y);
  270.   x = y;
  271. end;
  272.  
  273. define method \< (x :: <real>, y :: <real>)
  274.   let (x, y) = compare-contagion(x, y);
  275.   x < y;
  276. end;
  277.  
  278. define method \<= (x :: <real>, y :: <float>)
  279.   let (x, y) = compare-contagion(x, y);
  280.   x <= y;
  281. end;
  282.  
  283. define method \<= (x :: <float>, y :: <real>)
  284.   let (x, y) = compare-contagion(x, y);
  285.   x <= y;
  286. end;  
  287.  
  288.  
  289.  
  290. // Other routines.
  291.  
  292. define method \^ (base :: <number>, power :: <integer>)
  293.   case
  294.     negative? (power) =>
  295.       1 / (base ^ (- power));
  296.     base == 2 =>
  297.       ash (1, power);
  298.     otherwise =>
  299.       for (power = power then ash (power, -1),
  300.        total = 1 then if (odd? (power)) base * total else total end,
  301.        base = base then base * base,
  302.        until zero? (power))
  303.       finally
  304.     total;
  305.       end;
  306.   end;
  307. end;
  308.  
  309. define method abs (real :: <real>)
  310.   if (negative?(real))
  311.     -real;
  312.   else
  313.     real;
  314.   end;
  315. end;
  316.  
  317. define method logior (#rest integers)
  318.   reduce(binary-logior, 0, integers);
  319. end;
  320.  
  321. define method logxor (#rest integers)
  322.   reduce(binary-logxor, 0, integers);
  323. end;
  324.  
  325. define method logand (#rest integers)
  326.   reduce(binary-logand, -1, integers);
  327. end;
  328.  
  329. define method lcm (n :: <integer>, m :: <integer>)
  330.   truncate/(max(n, m), gcd(n, m)) * min(n, m);
  331. end;
  332.  
  333. define method gcd (u :: <integer>, v :: <integer>)
  334.   case
  335.     zero?(u) => v;
  336.     zero?(v) => u;
  337.     otherwise
  338.       for (k from 0,
  339.        u = abs(u) then ash(u, -1),
  340.        v = abs(v) then ash(v, -1),
  341.        until odd?(logior(u, v)))
  342.       finally
  343.     block (return)
  344.       for (temp = if (odd?(u)) -v else ash(u, -1) end
  345.          then ash(temp, -1))
  346.         if (odd?(temp))
  347.           if (positive?(temp))
  348.         u := temp;
  349.           else
  350.         v := -temp;
  351.           end;
  352.           temp := u - v;
  353.           if (zero?(temp))
  354.         return(ash(u, k));
  355.           end;
  356.         end if;
  357.       end for;
  358.     end block;
  359.       end for;
  360.   end case;
  361. end gcd;
  362.  
  363. define method min (x :: <real>, #rest more)
  364.   select (size(more))
  365.     0 => x;
  366.     1 =>
  367.       let y = first(more);
  368.       if (y < x) y else x end if;
  369.     otherwise =>
  370.       for (y in more,
  371.        result = x then if (y < result) y else result end)
  372.       finally
  373.     result;
  374.       end;
  375.   end select;
  376. end;
  377.  
  378. define method max (x :: <real>, #rest more)
  379.   select (size(more))
  380.     0 => x;
  381.     1 =>
  382.       let y = first(more);
  383.       if (y > x) y else x end if;
  384.     otherwise =>
  385.       for (y in more,
  386.        result = x then if (y > result) y else result end)
  387.       finally result;
  388.       end;
  389.   end select;
  390. end;
  391.  
  392.